/*
 * 
 * Copyright (C) 2010-2012 Wilfried Elmenreich, Anita Sobe 
 * This file is part of VideoNetwork.
 * 
 * VideoNetwork is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 
 * You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. 
 */
package proxy.repl;

import java.util.ArrayList;
import java.util.TreeMap;

import proxy.Configuration;
import proxy.Content;
import proxy.HormoneControls;
import proxy.Link;
import proxy.Migration;
import proxy.SearchServerNode;
import proxy.UnitContainer;
import simulation.Simulator;

public class SearchServerHormoneRanking extends SearchServerNode {

	double thresh;
	double maxRank = 0;

	double percOfTags;

	public SearchServerHormoneRanking(int id, Simulator simulator,
			Configuration config, HormoneControls hCtrl) {
		super(id, simulator, config, hCtrl);
		percOfTags = config.getPercOfTags();
	}

	@Override
	/**
	 * calculate group rank of neighbors and decide if the unit is worth to replicate
	 */
	protected Migration createMigration(UnitContainer uc, double highestPhero,
			Link bestlink) {
		Migration m = super.createMigration(uc, highestPhero, bestlink);
		ArrayList<Integer> rankedHormones = new ArrayList<Integer>();
		if (!m.isCopy()) {
			Content current = uc.getVideoUnit().getContent();
			int maxPopular = 0;
			// go through all neighbors and get the rank there
			for (Link li : links) {
				SearchServerNode neighbor = (SearchServerNode) li
						.getTargetNode();
				// a unit only has a rank if it is listed at the neighbor
				TreeMap<Content, Double> ht = neighbor.getHormoneTable();
				if (ht.containsKey(current)) {
					// get max hormone table length to calculate threshold
					int size = ht.size();
					if (size > maxPopular) {
						maxPopular = size;
					}
					ArrayList<Content> hormones = new ArrayList<Content>(
							ht.keySet());
					rankedHormones.add(hormones.indexOf(current));
				}
			}
//			Collections.sort(rankedHormones);
			double n = 1 / (double) rankedHormones.size();
			double sum = 0;
			for (int i = 0; i < rankedHormones.size(); i++) {
				sum += Math.log(rankedHormones.get(i) + 1);
			}
			maxRank = maxPopular * percOfTags;
			thresh = Math.log(Math.round(maxRank) + 1);
			if (n * sum <= thresh) {
				m.setCopy(true);
			}
//			 System.out.println(n + " " + sum + " " + rankedHormones.size()
//			 + " " + " hrating " + n * sum + " thresh " + thresh+
//			 " maxPop "+maxPopular+ " maxRank "+maxRank);
		}
		return m;
	}
}
